/*
 * Copyright (C), 2002-2017, 你的兔宝宝电子商务有限公司
 * FileName: SqlMapXmlResource.java
 * Author:   你的兔宝宝
 * Date:     2017-6-5 下午9:26:52
 * Description: sqlMap.xml自营处理//模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.baby.demo.utils.dal;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;

import com.baby.demo.utils.Collections;
import com.baby.demo.utils.Strings;
import com.baby.demo.utils.Xmls;

/**
 * 〈一句话功能简述〉<br> 
 * 〈功能详细描述〉
 *
 * @author 你的兔宝宝
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public class SqlMapXmlResource {
    
    private static Logger logger = LoggerFactory.getLogger(SqlFreeMarkerParser.class);
    
    /** SQL模板容器 */
    private Map<String, SqlMap> sqlContainer = new HashMap<String, SqlMap>();
    /** SQL资源模板*/
    private Resource[] resources;
    
    private String sql_id_tpl = "{namespace}.{id}";
    /**
     * 
     * 功能描述: 初始化sqlMap.xml资源文件<br>
     * 〈功能详细描述〉
     *
     * @param resources
     * @param sqlContainer
     * @Author:   你的兔宝宝
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void initialize(Resource[] resources){
        this.resources = resources;
        initialize();
    }
    
    /**
     * 
     * 功能描述: 初始化sqlMap.xml资源文件<br>
     * 〈功能详细描述〉
     *
     * @Author:   你的兔宝宝
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void initialize(){
        // 初始化sqlMap.xml资源文件
        if( resources != null ){
            SAXReader saxReader = new SAXReader();
            for( Resource resource : resources ){
                String fileName = resource.getFilename();
                try {
                    InputStream reader = resource.getInputStream();
                    Document doc = saxReader.read(reader);
                    Map<String,Object> xmlmap = Xmls.xml2map(doc,false);
                    parse(fileName,xmlmap);
                } catch (Exception e) {
                    throw new DalException("读取sqlMap.xml文件失败["+fileName+"]",e);
                }
            }
        }else{
            throw new DalException("初始化sqlMap.xml资源失败,resource:"+resources);
        }
    }
    
    @SuppressWarnings("unchecked")
    public void parse(String filename,Map<String,Object> xmlmap){
        String namespace = Strings.get(xmlmap, "namespace");
        if( Strings.isEmpty(namespace) ){
            throw new DalException("sqlMap.xml文件["+filename+"]参数[namespace]为空");
        }
        List<Map<String,Object>> sqlMaps = Collections.path2list(xmlmap, "sql");
        for( Map<String,Object> sqlMap : sqlMaps ){
            String sqlId = Strings.get(sqlMap, "id");
            if( Collections.isEmpty(sqlMap,"id","text") ){
                throw new DalException("sqlMap.xml文件["+filename+"]id["+sqlId+"]的sql为空");
            }
            if( Collections.isEmpty(sqlMap,"jdbcTimeout") ){
                Collections.copy(xmlmap,sqlMap,"jdbcTimeout");
            }
            sqlId = Strings.format(sql_id_tpl, xmlmap,sqlMap);
            if( sqlContainer.containsKey(sqlId) ){
                logger.debug("sqlMap.xml[{}]存在相同id[{}]的sql",new Object[]{filename,sqlId});
            }
            sqlMap.put("sqlId", sqlId);
            sqlMap.put("filename", filename);
            sqlContainer.put(sqlId, new SqlMap(sqlMap));
        }
    }
    
    /**
     * 
     * 功能描述: 获取指定sqlId的sqlMap<br>
     * 〈功能详细描述〉
     *
     * @param sqlId
     * @return
     * @Author:   你的兔宝宝
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    protected SqlMap getSqlMap(String sqlId) {
        SqlMap sqlMap = sqlContainer.get(sqlId);
        if( sqlMap == null || Strings.isEmpty(sqlMap.content) ){
            throw new DalException("指定sqlId的sql不存在"+sqlId);
        }
        return sqlMap;
    }
    
    
    /**
     * @param resources the resources to set
     */
    public void setResources(Resource[] resources) {
        this.resources = resources;
    }

    /**
     * @return the resources
     */
    public Resource[] getResources() {
        return resources;
    }

    /**
     * @return the sql_id_tpl
     */
    public String getSql_id_tpl() {
        return sql_id_tpl;
    }

    /**
     * @param sql_id_tpl the sql_id_tpl to set
     */
    public void setSql_id_tpl(String sql_id_tpl) {
        this.sql_id_tpl = sql_id_tpl;
    }
    
    
}
